package com.lanyou.esb.web.serviceChannelManagement;

import java.io.IOException;
import java.math.BigInteger;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.http.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lanyou.cook.common.Constants;
import com.lanyou.cook.entity.domain.userManagement.User;
import com.lanyou.cook.service.security.UserSessionService;
import com.lanyou.cook.util.gson.GsonUtil;
import com.lanyou.esb.common.CommonUtils;
import com.lanyou.esb.datadictionary.TokenStatus;
import com.lanyou.esb.entity.Http;
import com.lanyou.esb.entity.Token;
import com.lanyou.esb.repository.ServiceChannelManagerRepository;
import com.lanyou.esb.service.ServiceAccessApplicationService;
import com.lanyou.esb.web.param.InterfaceTokenParam;

/**
 * 服务接入管理控制器
 * 
 * @author Davey.wu
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/serviceAccessManagement")
public class ServiceAccessManagementController {
	@Autowired
	ServiceAccessApplicationService serviceAccessApplicationService;

	@Autowired
	private ServiceChannelManagerRepository serviceChannelManagerRepository;

	@Autowired
	private UserSessionService userSessionService;

	private static FastDateFormat FASTDATEFORMAT_YYYYMMDDHHMMSS = FastDateFormat
			.getInstance(Constants.DATETIME_PATTERN_1);

	/**
	 * 获取TOKEN，分页
	 * 
	 * @param param
	 * @param pageable
	 * @return
	 */
	@RequestMapping("/findInterfaceTokenInfos")
	public Page<Token> findInterfaceTokenInfos(InterfaceTokenParam param,
			Pageable pageable) {
		User user = userSessionService.getCurrentAuthenticatedUser();
		if (StringUtils.isNotBlank(param.getInterfaceName())) {
			param.setInterfaceName("%" + param.getInterfaceName() + "%");
		}
		if (StringUtils.isNotBlank(param.getAppUserCode())) {
			param.setAppUserCode("%" + param.getAppUserCode() + "%");
		}
		// 当前时间
		Date now = new Date();
		// 是否过期
		boolean expire = false;
		String status = param.getStatus();
		if (StringUtils.isNotBlank(param.getStatus())
				&& TokenStatus.EXPIRE.ValueCode.equals(param.getStatus())) {
			expire = true;
			status = TokenStatus.ENABLE.ValueCode;
		}
		// 查看总记录数
		List<Object> totals = serviceChannelManagerRepository
				.findInterfaceTokenTotalNum(
						param.getInterfaceName(),
						param.getPubFieldId(),
						param.getCallFieldId(),
						param.getPubSystemId(),
						param.getCallSystemId(),
						status,
						param.getAppUserCode(),
						param.getAppStartDate(),
						param.getAppEndDate(),
						param.getIsEnable(),
						user.getId(),
						expire ? FASTDATEFORMAT_YYYYMMDDHHMMSS.format(now) : "",
						(TokenStatus.ENABLE.ValueCode.equals(status) && !expire) ? FASTDATEFORMAT_YYYYMMDDHHMMSS
								.format(now) : "");
		BigInteger total = null;
		if (totals != null && totals.size() > 0) {
			total = (BigInteger) totals.get(0);
		}
		if (total == null || total.longValue() <= 0) {
			return new PageImpl<Token>(new ArrayList<Token>(0), pageable, 0);
		}
		List<Object[]> list = serviceChannelManagerRepository
				.findInterfaceTokenInfos(
						param.getInterfaceName(),
						param.getPubFieldId(),
						param.getCallFieldId(),
						param.getPubSystemId(),
						param.getCallSystemId(),
						status,
						param.getAppUserCode(),
						param.getAppStartDate(),
						param.getAppEndDate(),
						param.getIsEnable(),
						user.getId(),
						expire ? FASTDATEFORMAT_YYYYMMDDHHMMSS.format(now) : "",
						(TokenStatus.ENABLE.ValueCode.equals(status) && !expire) ? FASTDATEFORMAT_YYYYMMDDHHMMSS
								.format(now) : "", pageable.getPageNumber()
								* pageable.getPageSize(), pageable
								.getPageSize());

		List<Token> result = new ArrayList<Token>(list.size());
		// 转换结果集
		for (Object[] object : list) {
			Token token = new Token();
			token.setId((String) object[0]);
			Http http = new Http();
			String id = object[1] != null ? (String) object[1] : "";
			http.setId(id);
			token.setHttp(http);
			token.setInterfaceName(object[2] != null ? (String) object[2] : "");
			token.setInterfaceCode(object[3] != null ? (String) object[3] : "");
			token.setAppKey(object[4] != null ? (String) object[4] : "");
			token.setApplyUserCode(object[5] != null ? (String) object[5] : "");
			token.setStatus(object[6] != null ? (String) object[6] : "");
			token.setIsEnable(object[7] != null ? (String) object[7] : "");
			token.setApplyDate(object[8] != null ? ((Date) object[8]) : null);
			token.setInterfacePubSystemId(object[9] != null ? (String) object[9]
					: "");
			token.setInterfacePubSystemCode(object[10] != null ? (String) object[10]
					: "");
			token.setInterfacePubSystemName(object[11] != null ? (String) object[11]
					: "");
			token.setInterfaceCallSystemId(object[12] != null ? (String) object[12]
					: "");
			token.setInterfaceCallSytemCode(object[13] != null ? (String) object[13]
					: "");
			token.setInterfaceCallSytemName(object[14] != null ? (String) object[14]
					: "");
			token.setKeyInvalidDate(object[15] != null ? ((Date) object[15])
					: null);
			// 令牌非未生效且有效期不为空，需要判断令牌是否已过有效期
			if (!TokenStatus.DISABLE.ValueCode.equals(token.getStatus())
					&& token.getKeyInvalidDate() != null) {
				// 密钥是否过期
				if (token.getKeyInvalidDate().before(now)) {
					token.setStatus(TokenStatus.EXPIRE.ValueCode);
				}
			}
			result.add(token);
		}
		Page<Token> page = new PageImpl<Token>(result, pageable,
				total.longValue());
		return page;
	}

	/**
	 * 更新TOKEN状态
	 * 
	 * @param id
	 * @param status
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	@RequestMapping(value = "/updateStatus", produces = "application/json")
	public String updateStatus(String id, String status) throws HttpException,
			IOException, URISyntaxException {
		Map<String, Object> map = new HashMap<>();
		String errorMsg = "";
		if (StringUtils.isBlank(id)) {
			errorMsg = "令牌标识不能为空";
		}
		if (StringUtils.isBlank(status)) {
			errorMsg = "状态不能为空";
		}
		if (StringUtils.isNotBlank(errorMsg)) {
			map.put(CommonUtils.MSG_FIELD_RESULT, false);
			map.put(CommonUtils.MSG_FIELD_MSG, errorMsg);
			return GsonUtil.getDefaultGson().toJson(map);
		}

		try {
			serviceAccessApplicationService.updateStatus(id, status);
			map.put(CommonUtils.MSG_FIELD_RESULT, true);
		} catch (Exception e) {
			map.put(CommonUtils.MSG_FIELD_RESULT, false);
			map.put(CommonUtils.MSG_FIELD_MSG, e.getMessage());
		}
		return GsonUtil.getDefaultGson().toJson(map);
	}

	/**
	 * 修改密钥有效期
	 * 
	 * @param id
	 * @param date
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 * @throws URISyntaxException
	 */
	@RequestMapping(value = "/updateKeyInvalidDate", produces = "application/json")
	public String updateKeyInvalidDate(String id, String date)
			throws HttpException, IOException, URISyntaxException {
		Map<String, Object> map = new HashMap<>();
		String errorMsg = "";
		if (StringUtils.isBlank(id)) {
			errorMsg = "令牌标识不能为空";
		}
		if (StringUtils.isBlank(date)) {
			errorMsg = "失效时间不能为空";
		}
		Date invalidDate = null;
		try {
			invalidDate = FASTDATEFORMAT_YYYYMMDDHHMMSS.parse(date);
		} catch (Exception e) {
			errorMsg = "时间格式不对，格式应该是：yyyy-MM-dd HH:mm:ss";
		}
		if (StringUtils.isNotBlank(errorMsg)) {
			map.put(CommonUtils.MSG_FIELD_RESULT, false);
			map.put(CommonUtils.MSG_FIELD_MSG, errorMsg);
			return GsonUtil.getDefaultGson().toJson(map);
		}
		try {
			serviceAccessApplicationService.updateKeyInvalidDate(id,
					invalidDate);
			map.put(CommonUtils.MSG_FIELD_RESULT, true);
		} catch (Exception e) {
			map.put(CommonUtils.MSG_FIELD_RESULT, false);
			map.put(CommonUtils.MSG_FIELD_MSG, e.getMessage());
		}
		return GsonUtil.getDefaultGson().toJson(map);
	}
}
